<template>
    <TheElDialog :title="title" :visible.sync="centerDialogVisible" @close="handleCenterDialogClose" v-bind="$attrs">
        <el-form
            @submit.native.prevent
            ref="formRule"
            :model="form"
            :rules="rules"
            :label-width="isMobile ? '80px' : '120px'"
        >
            <el-form-item prop="name" label="名称">
                <el-input
                    :disabled="isDetail"
                    v-model="form.name"
                    placeholder="请填写账单名称"
                    :style="inputStyle"
                ></el-input>
            </el-form-item>
            <el-form-item prop="platform" label="借款平台">
                <el-select v-model="form.platform" filterable clearable placeholder="请选择" :style="inputStyle">
                    <el-option
                        :disabled="isDetail"
                        v-for="item in optionsPlatforms"
                        :key="item._id"
                        :label="`${item.name}`"
                        :value="item.id"
                    >
                    </el-option>
                </el-select>
            </el-form-item>
            <el-form-item prop="total" label="借款金额">
                <el-input
                    :disabled="isDetail"
                    v-model="form.total"
                    placeholder="请填写账单借款金额"
                    :style="inputStyle"
                ></el-input
                ><span class="sign">元</span>
            </el-form-item>
            <el-form-item prop="rate" label="综合年化费率">
                <el-input
                    :disabled="isDetail"
                    v-model="form.rate"
                    placeholder="请填写账单综合年化费率"
                    :style="inputStyle"
                ></el-input
                ><span class="sign">%</span>
                <span class="sign small">年利率 = 月利率 * 12 = 日利率 * 360</span>
            </el-form-item>
            <el-form-item prop="from_time" label="借款时间">
                <el-date-picker
                    :disabled="isDetail"
                    v-model="form.from_time"
                    type="datetime"
                    placeholder="请填写账单借款时间"
                    :style="inputStyle"
                    :editable="isMobile ? false : true"
                    :align="isMobile ? 'right' : 'left'"
                >
                </el-date-picker>
            </el-form-item>
            <el-form-item prop="start_time" label="开始还款日期">
                <el-date-picker
                    :disabled="isDetail"
                    v-model="form.start_time"
                    type="date"
                    placeholder="请填写账单开始还款日期"
                    :style="inputStyle"
                    :editable="isMobile ? false : true"
                    :align="isMobile ? 'right' : 'left'"
                    @change="handleChangeRate('start_time')"
                >
                </el-date-picker>
            </el-form-item>

            <el-form-item prop="type" label="还款方式">
                <div>
                    <el-radio v-model="form.type" label="1" border>等额本息</el-radio>
                    <el-radio v-model="form.type" label="2" border>自定义</el-radio>
                </div>
            </el-form-item>

            <el-form-item prop="stage_total" label="总分期数">
                <el-input-number
                    :disabled="isDetail"
                    v-model="form.stage_total"
                    :min="0"
                    :max="72"
                    placeholder="请填写账单总分期数"
                    :style="inputStyle"
                    @change="handleChangeRate('stage_total')"
                >
                </el-input-number>
            </el-form-item>
            <el-form-item prop="stages" label="分期账单" class="bill-stage-wrapper">
                <template v-if="!form.stage_total">
                    无
                </template>
                <template v-else>
                    <div class="bill-topwrap">
                        <el-button @click="isShowAll = !isShowAll" type="text">
                            {{ isShowAll ? '收起所有分期账单' : '展开所有分期账单' }}
                        </el-button>
                        <el-button
                            :disabled="isDetail"
                            v-show="isShowAll"
                            @click="handleEditAll(!isEditAll)"
                            type="text"
                            class="btn-all"
                        >
                            {{ isEditAll ? '收起批量编辑' : '展开批量编辑' }}
                        </el-button>
                    </div>
                    <el-card
                        v-show="isShowAll"
                        v-for="(item, index) in form.stages"
                        :key="index"
                        :body-style="{padding: '15px 20px'}"
                        :class="{
                            isInfo: item.status === 1,
                            isSuccess: item.status === 2,
                            isDanger: item.status === 3
                        }"
                        class="bill-stage-item"
                    >
                        <div class="bill-stage-head">
                            <span>应还金额（元）</span>
                            <span>|</span>
                            <span> {{ item.stage }}/{{ form.stage_total }}期 </span>
                            <span>
                                <template v-if="item.isEdit">
                                    <el-select v-model="item.status" placeholder="选择还款状态" style="width: 150px;">
                                        <el-option label="还款中" :value="1"></el-option>
                                        <el-option label="已结清" :value="2"></el-option>
                                        <el-option label="已逾期" :value="3"></el-option>
                                    </el-select>
                                </template>
                                <template v-else>
                                    <span class="tip-text">{{ item.status | filterStatus }}</span>
                                </template>
                            </span>
                            <span>
                                <el-button
                                    :disabled="isDetail"
                                    @click="handleEditItem(form.stages, index)"
                                    class="btn-edit"
                                    type="text"
                                >
                                    {{ item.isEdit ? '收起编辑' : '展开编辑' }}
                                </el-button>
                            </span>
                        </div>
                        <div class="bill-stage-cash">
                            <template v-if="item.isEdit">
                                <el-input
                                    @change="handleChangeItemCash"
                                    style="width: 150px;"
                                    placeholder="请输入金额"
                                    v-model="item.cash"
                                ></el-input>
                            </template>
                            <template v-else>
                                {{ item.cash }}
                            </template>
                        </div>

                        <div class="bill-stage-time">还款时间：{{ moment(item.date).format('YYYY-MM-DD') }}</div>
                    </el-card>
                </template>
            </el-form-item>
            <el-form-item prop="total_all" label="合计需还">
                <el-input
                    :disabled="true"
                    v-model="form.total_all"
                    placeholder="请填写账单合计需还"
                    :style="inputStyle"
                ></el-input>
                <span class="sign">元</span>
                <span class="sign small">根据分期账单生成 无需手动输入</span>
            </el-form-item>
            <el-form-item prop="bank" label="还款银行">
                <el-input :disabled="isDetail" v-model="form.bank" placeholder="请填写账单还款银行"></el-input>
            </el-form-item>
            <el-form-item prop="bank_number" label="银行卡后四位">
                <el-input
                    :disabled="isDetail"
                    v-model="form.bank_number"
                    placeholder="请填写账单还款银行卡后四位"
                ></el-input>
            </el-form-item>
            <el-form-item prop="remark" label="备注">
                <el-input
                    :disabled="isDetail"
                    type="textarea"
                    v-model="form.remark"
                    placeholder="请填写账单备注"
                ></el-input>
            </el-form-item>
        </el-form>
        <span slot="footer" class="dialog-footer">
            <el-button :disabled="centerDialogLoading" @click="centerDialogVisible = false">取 消</el-button>
            <el-button
                :disabled="isDetail"
                :loading="centerDialogLoading"
                type="primary"
                @click="handleSubmit('formRule')"
                >确 定</el-button
            >
        </span>
    </TheElDialog>
</template>
<script>
import moment from 'moment';
import {putBillList, postBillList} from '../../api/bill';
import {deepCopy, equivalentPrincipal} from '../../utils/utils';
import {BASIC_MONEY} from '../../utils/constant';
import {
    validateStages,
    validateStartTime,
    validateTotal,
    validateTotalAll,
    validateRate,
    validateStageTotal
} from './validation';
export default {
    name: 'CreateBill',
    props: {
        optionsPlatforms: {
            type: Array,
            required: true,
            default: () => []
        },
        title: {
            type: String,
            default: '账单'
        },
        visible: {
            type: Boolean,
            default: false
        },
        dataSource: {
            type: Object,
            default: () => ({
                platform: '',
                name: '',
                from_time: null,
                total: null,
                total_all: null,
                stage_total: 0,
                rate: null,
                type: '2', // 还款方式： '1' 等额本息 '2' 自定义
                bank: null,
                bank_number: null,
                remark: '',
                stages: []
            })
        }
    },
    filters: {
        filterStatus(value) {
            let statusText = '';
            switch (value) {
                case 1:
                    statusText = '还款中';
                    break;
                case 2:
                    statusText = '已结清';
                    break;
                case 3:
                    statusText = '已逾期';
                    break;
                default:
                    break;
            }
            return statusText;
        }
    },
    data() {
        return {
            moment,
            // 新建账单弹窗
            // centerDialogVisible: false,
            // 新建账单弹窗 提交表单中
            centerDialogLoading: false,
            // 编辑分期账单
            isEditAll: false,
            // 隐藏展示 分期账单
            isShowAll: true,
            inputStyle: {width: '100%', maxWidth: '320px'},

            // 新建账单表单
            form: {
                name: '',
                platform: '',
                from_time: null,
                total: null,
                total_all: null,
                stage_total: 0,
                rate: null,
                bank: null,
                type: '1', // 还款方式： '1' 等额本息 '2' 自定义
                bank_number: null,
                remark: '',
                stages: []
            },
            rules: {
                name: [{required: true, message: '请填写账单名称', trigger: ['change', 'blur']}],
                from_time: [{required: true, message: '请填写借款时间', trigger: ['change', 'blur']}],
                start_time: [
                    {required: true, message: '请填写开始还款日期', trigger: ['change', 'blur']},
                    {validator: validateStartTime, trigger: ['change', 'blur']}
                ],
                total: [
                    {required: true, message: '请填写账单借款金额', trigger: ['change', 'blur']},
                    {validator: validateTotal, trigger: ['change', 'blur']}
                ],
                total_all: [
                    {required: true, message: '请填写账单合计需还', trigger: ['change', 'blur']},
                    {validator: validateTotalAll, trigger: ['change', 'blur']}
                ],
                stage_total: [
                    {required: true, message: '请填写账单总分期数', trigger: ['change', 'blur']},
                    {validator: validateStageTotal, trigger: ['change', 'blur']}
                ],
                rate: [
                    {required: true, message: '请填写账单年利率', trigger: ['change', 'blur']},
                    {validator: validateRate, trigger: ['change', 'blur']}
                ],
                bank: [{required: true, message: '请填写账单还款银行', trigger: ['change', 'blur']}],
                bank_number: [{required: true, message: '请填写账单还款银行卡后四位', trigger: ['change', 'blur']}],
                stages: [
                    {required: true, message: '请填写账单分期账单', trigger: ['change', 'blur']},
                    {validator: validateStages, trigger: ['change', 'blur']}
                ]
                // remark: [{required: false, message: '请填写账单备注', trigger: ['change', 'blur']}]
            }
        };
    },
    computed: {
        isMobile() {
            return this.$store.getters['app/isMobile'];
        },
        formStages() {
            return this.form.stages;
        },
        isDetail() {
            return this.title === '查看账单';
        },
        centerDialogVisible: {
            get() {
                return this.visible;
            },
            set(val) {
                this.$emit('update:visible', val);
            }
        }
    },
    watch: {
        dataSource: {
            handler(val) {
                const newItem = deepCopy(val);
                if (newItem.platform) {
                    newItem.platform = newItem.platform._id;
                }
                this.form = newItem;
                this.isEdit = this.handleIsEditAll(deepCopy(val.stages));
            },
            deep: false,
            immediate: false
        },
        formStages: {
            handler(val) {
                const stages = val || [];
                const totalAll = stages.reduce((total, cur) => {
                    return (total * 100 + (cur.cash - 0) * 100) / 100;
                }, 0);
                this.form.total_all = totalAll.toFixed(2) - 0;
            },
            deep: false,
            immediate: false
        }
    },
    methods: {
        // 提交账单
        handleSubmit(formName) {
            this.$refs[formName].validate((valid, fields) => {
                // eslint-disable-next-line
                const {total, total_all, rate} = this.form;
                if (valid) {
                    const stages = this.form.stages.map(item => {
                        return {...item, cash: item.cash - 0};
                    });
                    const newBill = {
                        ...this.form,
                        total: total - 0,
                        total_all: total_all - 0, // eslint-disable-line
                        rate: rate - 0,
                        stages
                    };
                    newBill.total = newBill.total * BASIC_MONEY;
                    newBill.total_all = newBill.total_all * BASIC_MONEY;

                    newBill.stages = newBill.stages.map(item => {
                        return {...item, cash: item.cash * BASIC_MONEY};
                    });
                    if (this.title === '新建账单') {
                        this.handleCreateBill(newBill);
                    }
                    if (this.title === '编辑账单') {
                        this.handlePutBill(newBill);
                    }
                } else {
                    const first = Object.keys(fields)[0];
                    const items = fields[first] || [];
                    const {message} = items[0] || {};
                    this.$message({showClose: true, type: 'error', message});
                }
            });
        },
        // 创建账单
        handleCreateBill(newBill) {
            this.centerDialogLoading = true;

            postBillList(newBill)
                .then(({data: res}) => {
                    if (res.status === 201) {
                        this.$message({showClose: true, type: 'success', message: '创建账单成功'});
                        this.centerDialogVisible = false;
                        // this.getList();
                        // 重新更新数据
                        this.$emit('on-ok');
                    } else {
                        throw new Error(res);
                    }
                })
                .finally(() => {
                    this.centerDialogLoading = false;
                });
        },
        // 更新
        handlePutBill(newBill) {
            this.centerDialogLoading = true;
            putBillList(newBill._id, newBill)
                .then(({data: res}) => {
                    if (res.status === 204) {
                        this.$message({showClose: true, type: 'success', message: '更新账单成功'});
                        this.centerDialogVisible = false;
                        // 重新更新数据
                        this.$emit('on-ok');
                    } else {
                        throw new Error(res);
                    }
                })
                .finally(() => {
                    this.centerDialogLoading = false;
                });
        },
        // 编辑单个账单
        handleEditItem(stages, index) {
            // item.isEdit = !item.isEdit;
            const newStages = deepCopy(stages);
            newStages[index].isEdit = !newStages[index].isEdit;

            this.form = {...this.form, stages: newStages};

            this.isEditAll = this.handleIsEditAll(newStages);
            // const isEditY = newStages.map(y => {
            //     return y.isEdit;
            // });

            // this.isEditAll = !isEditY.every(i => i === false);
        },
        // 关闭、编辑 全部账单
        handleIsEditAll(stages) {
            if (!stages) {
                return false;
            }
            const isEditY = stages.map(y => {
                return y.isEdit;
            });

            return !isEditY.every(i => i === false);
        },

        // 编辑全部账单
        handleEditAll(isEditAll) {
            const stages = this.form.stages.map(item => {
                return {...item, isEdit: isEditAll};
            });
            this.form = {...this.form, stages};
            this.isEditAll = isEditAll;
        },
        // 创建账单
        handleChangeStage(value, config) {
            const totalAll = this.form.total_all || 0;
            const type = this.form.type;
            const startTime = this.form.start_time;
            const dateArr = this.handleCreateDate(value - 0, startTime);
            const newCash = ((totalAll - 0) * 100) / value;
            const cash = (newCash / 100).toFixed(2) - 0;
            const length = value - 0;
            let stages = [];

            if (config.start_time && length > 0) {
                // 如果现在修改开始还款时间
                stages = this.form.stages.map((item, index) => {
                    return {...item, date: dateArr[index]};
                });
            } else if (config.total_all && length > 0) {
                this.handleChangeType(type);
                if (type === '2') {
                    // this.$message({type: 'success', message: '你的还款方式为自定义，请手动填写每期还款金额'});
                    return;
                }
                // 如果现在修改合计需还款
                stages = this.form.stages.map((item, index) => {
                    return {...item, cash: cash};
                });
            } else {
                for (let i = 0; i < length; i++) {
                    const newStage = {
                        cash: cash,
                        date: dateArr[i],
                        stage: i + 1,
                        // stage_all: 6,
                        status: 1, // 1 还款中 2已结清
                        isEdit: false // 是否可编辑
                    };

                    stages.push(newStage);
                }
            }

            // this.form = {...this.form, stages};
            // this.$nextTick(() => {
            //     this.$refs['formRule'].validateField('stages');
            // });
        },
        // 生成时间账单时间
        handleCreateDate(stageTotal, startTime) {
            const year = moment(startTime).format('YYYY') - 0;
            const month = moment(startTime).format('MM') - 0;
            const day = moment(startTime).format('DD') - 0;
            /**
            1. stageTotal 为数组长度
            2. 如果 month === 12，
                    下一个month为 1
                    year = year + 1
             */
            let currentYear = year;
            let currentMonth = month;
            let output;
            const arr = new Array(stageTotal).fill('');
            return arr.map((item, index) => {
                if (currentMonth >= 12) {
                    output = `${currentYear}-${(currentMonth + '').padStart(2, '0')}-${day}`;
                    currentMonth = 1;
                    currentYear = currentYear + 1;
                } else {
                    output = `${currentYear}-${(currentMonth + '').padStart(2, '0')}-${day}`;
                    currentMonth = currentMonth + 1;
                }
                return output;
            });
        },
        // dialog 关闭
        handleCenterDialogClose() {
            // 关闭
            this.$emit('close');
            this.isShowAll = true;
            this.isEditAll = false;
            this.form = {
                name: '',
                from_time: null,
                total: null,
                total_all: null,
                stage_total: 0,
                rate: null,
                bank: null,
                type: '1', // 还款方式： '1' 等额本息 '2' 自定义
                bank_number: null,
                remark: '',
                stages: []
            };
        },
        // 改变type值
        handleChangeType(type) {
            // const h = this.$createElement;
            // let textHead = '自定义';
            // let textBody = '请手动填写分期账单的每期还款金额';
            // let color = colorDanger;
            // if (type === '1') {
            //     textHead = '等额本息';
            //     textBody = '系统自动将根据你的 合计需还 为您重新生成每期账单还款金额';
            //     color = colorSuccess;
            // }
            // this.$notify({
            //     title: `${textHead} 为您的还款方式`,
            //     message: h('i', {style: `color: ${color};font-size: 20px;`}, textBody),
            //     duration: 15000
            // });
        },
        // 计算date1 ~ date2 之间跨度了几个月
        // 比如：同年同月 跨度为0
        // 同年，date2 2月 date1 1月 跨度为1
        calcHowMonth(date1, date2) {
            const date1YYYY = moment(date1).format('YYYY') - 0;
            const date1MM = moment(date1).format('MM') - 0;
            const date1DD = moment(date2).format('DD') - 0;

            const date2YYYY = moment(date2).format('YYYY') - 0;
            const date2MM = moment(date2).format('MM') - 0;
            const date2DD = moment(date2).format('DD') - 0;
            // 跨度多少个月
            let count;

            // 已知date2 必须大于date1
            if (date1YYYY === date2YYYY) {
                count = date2MM - date1MM;
            } else {
                const yyyy = date2YYYY - date1YYYY;
                // yyyy === 2 , month = 12 + sum1
                // sum = 12 + date2MM - date1MM

                // yyyy === 3 , month = 12(yyyy -1) + sum1
                // sum = 12 + date2MM - date1MM
                const sum1 = 12 + date2MM - date1MM;
                count = 12 * (yyyy - 1) + sum1;
            }
            return {count, date1YYYY, date1MM, date1DD, date2YYYY, date2MM, date2DD};
        },
        // 创建分期账单
        handleChangeRate(type) {
            // 年利率，借款本金，分期数，借款日期，开始还款日期
            // eslint-disable-next-line
            const {rate, total, stage_total, from_time, start_time} = this.form;

            // 借款日期
            const date1 = moment(moment(from_time).format('YYYY-MM-DD')).valueOf();
            // 开始还款日期
            const date2 = moment(moment(start_time).format('YYYY-MM-DD')).valueOf();
            // 开始借款日到开始还款日的接口时长
            const days = (date2 - date1) / (1000 * 60 * 60 * 24);

            // 借款时间的下一个还款日期
            let nextDate = date2;

            // 计算跨度几个月还款
            // 跨度日期天数 > 0 为大于1期 ， === 0 为等于1期， < 0 为小于1期
            const {count, date1YYYY, date1MM, date1DD, date2DD} = this.calcHowMonth(date1, date2);
            // eslint-disable-next-line
            if (stage_total !== 1 && count > 1) {
                // 大于等于1
                // 相当于下下一个月开始还款
                // 那么需要用上一个还款日进行计算利息
                const dd = date2DD;
                const nextMM = date1MM === 12 ? 1 : date1MM + 1;
                const nextYYYY = date1MM === 12 ? date1YYYY + 1 : date1YYYY;
                nextDate = moment(`${nextYYYY}-${nextMM}-${dd}`).valueOf();
            }

            const useDay = (nextDate - date1) / (1000 * 60 * 60 * 24);
            // 日利率
            const dayRate = (rate * 100) / (360 * 10000);
            // 借款日 到 开始还款日 利息
            const firstDateInterest = ((dayRate * 10000 * useDay * total) / 10000).toFixed(2) - 0;

            const monthCash = equivalentPrincipal(total, rate, stage_total, 'year').toFixed(2) - 0;
            let output = [];
            // eslint-disable-next-line
            if (stage_total > 1) {
                output = new Array(stage_total).fill(monthCash);
            }
            // eslint-disable-next-line
            if (stage_total === 1) {
                output = [total];
            }

            if (output.length > 0) {
                const item = output[0] || 0;
                output[0] = (item * 100 + firstDateInterest * 100) / 100;
            }

            const dates = this.handleCreateDate(stage_total, start_time);

            const length = this.formStages.length;
            const oLength = output.length;
            let stages;
            if (type === 'start_time') {
                stages = this.formStages.map((item, index) => ({...item, date: dates[index]}));
            } else {
                // 分期账单数据
                stages = output.map((item, index) => {
                    const status = length === oLength && length > 0 ? this.formStages[index].status : 1;
                    return {
                        date: dates[index],
                        // cash: item, // 修改日期，数据全部被修改问题
                        stage: index + 1,
                        // stage_all: 6,
                        status: status, // 1 还款中 2已结清
                        isEdit: false // 是否可编辑
                    };
                });
            }

            this.form = {...this.form, stages};
            // this.$nextTick(() => {
            //     this.$refs['formRule'].validateField('stages');
            // });
        },
        // 对单个账单进行修改时 重新计算
        handleChangeItemCash() {
            this.form = {...this.form};
        }
    }
};
</script>

<style lang="scss" scoped>
@import '@/styles/variables.scss';
.small {
    font-size: 12px;
}
.bill-topwrap {
    display: flex;
    margin-bottom: 10px;
    .btn-all {
        margin-left: auto;
    }
}
.sign {
    display: inline-block;
    padding-left: 10px;
}
.bill-stage-editor {
    display: flex;
    justify-content: flex-end;
}
.bill-stage-wrapper {
    .bill-stage-item.isInfo {
        .tip-text {
            color: $--color-success;
        }
    }
    .bill-stage-item.isDanger {
        .tip-text {
            color: $--color-danger;
        }
    }
    .bill-stage-item.isSuccess {
        opacity: 0.5;
        .tip-text {
            color: $--color-info;
        }
    }
    .bill-stage-item {
        margin-bottom: 10px;
        line-height: 1em;
        .btn-edit {
            padding: 0;
        }
        .bill-stage-head {
            display: flex;
            flex-flow: row nowrap;
            & > span:nth-child(2) {
                margin: 0 20px;
            }
            & > span:nth-child(3) {
                margin-right: 25px;
            }
            & > span:last-child {
                // margin-right: 20px;
                margin-left: auto;
            }
        }
        .bill-stage-cash {
            padding: 10px 0;
        }
    }
}
</style>
